# -*- coding: utf-8 -*-
# Python中默认的编码格式是 ASCII 格式，在没修改编码格式时无法正确打印汉字，所以在读取中文时会报错。

# 元组用 () 标识。内部元素用逗号隔开。但是元组不能二次赋值，相当于只读列表。
# tuple的元素不能该变，它也没有append()，insert()这样的方法。
# 元祖 不可变的列表称为元祖  相当于数组

# 这里有一个非常值得探讨的问题，我们已经有了列表这种数据结构，为什么还需要元组这样的类型呢？
#
# 1.元组中的元素是无法修改的，事实上我们在项目中尤其是多线程环境（后面会讲到）中可能更喜欢使用的是那些不变对象
# （一方面因为对象状态不能修改，所以可以避免由此引起的不必要的程序错误，
# 简单的说就是一个不变的对象要比可变的对象更加容易维护；
# 另一方面因为没有任何一个线程能够修改不变对象的内部状态，
# 一个不变对象自动就是线程安全的，这样就可以省掉处理同步化的开销。
# 一个不变对象可以方便的被共享访问）。所以结论就是：如果不需要对元素进行添加、删除、修改的时候，可以考虑使用元组，
# 当然如果一个方法要返回多个值，使用元组也是不错的选择。

# 2.元组在创建时间和占用的空间上面都优于列表。
# 我们可以使用sys模块的getsizeof函数来检查存储同样的元素的元组和列表各自占用了多少内存空间，这个很容易做到。
# 我们也可以在ipython中使用魔法指令%timeit来分析创建同样内容的元组和列表所花费的时间，下图是我的macOS系统上测试的结果。

# tuple也可以用切片操作
tup1 = ('physics', 'chemistry', 1997, 2000)
tup2 = (1, 2, 3, 4, 5, 6, 7, 8)

print ("tup1[0]: ", tup1[0])
print ("tup2[1:5]: ", tup2[1:5])
print ("tup2[1:]: ", tup2[1:])

# 表面上看，tuple的元素确实变了，但其实变的不是tuple的元素，而是list的元素。
t = ('a', 'b', ['A', 'B'])
t[2][0] = 'X'
t[2][1] = 'Y'
print(t)

tup1 = (12, 34.56)
tup2 = ('abc', 'xyz')

# 以下修改元组元素操作是非法的。
# tup1[0] = 100

# 创建一个新的元组
tup3 = tup1 + tup2


from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])

p = Point(1, 2)

print(p.x, p[1])

